package com.example.mybubbleshooter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;

import android.R.integer;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.MediaPlayer;
import android.os.Vibrator;
import android.test.suitebuilder.TestSuiteBuilder.FailedToCreateTests;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

public class PlayView extends SurfaceView implements SurfaceHolder.Callback {

	final static boolean isRunning = true;
	Paint paint;

	MainThread thread;
	public Ball[] nextBalls = new Ball[2];
	public Ball misselBall;
	public static Queue<Ball> movingBalls;
	public static Ball movingBall;
	protected Bitmap scaled = null;
	public MediaPlayer sound = null;
	public static MediaPlayer hitSound = null;
	public MediaPlayer scoreSound = null;
	public static int ballLevel = 0;
	public static Ball targetBalls[] = new Ball[3];
	private static boolean ballOnMove = false;
	private static Ball[] fallingBallPosition;
	static Random generator;
	public static Vibrator v ;
	public static boolean se=false;
	public static boolean dow=false;
	
static Context con=null;
	public PlayView(Context context) {
		super(context);
		con=context;
		movingBalls = new LinkedList<Ball>();
		misselBall = Global.pool.poll();
		misselBall.setStatic(true);
		nextBalls[0] = Global.pool.poll();
		nextBalls[1] = Global.pool.poll();
		paint = new Paint();
		generator = new Random();
		getHolder().addCallback(this);
		// make the GamePanel focusable so it can handle events
		thread = new MainThread(getHolder(), this);
		setFocusable(true);
		

	}

	@Override
	public void onWindowFocusChanged(boolean hasWindowFocus) {

		super.onWindowFocusChanged(hasWindowFocus);
		// DisplayMetrics displaymetrics = new DisplayMetrics();
		// getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
		Global.width = getWidth();
		Global.height = getHeight();
		Global.misselY = Global.height - Global.ballRadius;
		misselBall.setCenterX(Global.misselX);
		misselBall.setCenterY(Global.misselY);
		nextBalls[0].setCenterX(Global.misselX + 4.0f * Global.ballRadius);
		nextBalls[0].setCenterY(Global.misselY);
		nextBalls[1].setCenterX(Global.misselX + 6.0f * Global.ballRadius);
		nextBalls[1].setCenterY(Global.misselY);
	}

	
	static boolean check(int i)
	{
		for(int j=0;j<8;j++)
		{
			if(Global.map[i][j]!=null)
				return true;
		}
		return false;
	}
	
	public String map(){
		String s="";
		for(int i=0;i<8;i++)
		{
			for(int j=0;j<8;j++)
			{
				if(Global.map[i][j]!=null)
				{
					s+="1,";
				}
				else
					s+="0";
			}
			s+="\n";
		}
		return s;
	}
	
	public void updateTime(){
		
		Global.per=(Global.per+1)%701;
		if(Global.per==700&&dow)
		{	
			
			
			
			Log.d("map", ".............................");
			if(check(Global.maxLayer-1))
				Global.maxLayer=Global.maxLayer+1;
			int lev=Global.maxLayer-1;
			
			int f=0;
			
			//oe=0 then the even row will replace the odd row and vice versa
			if(Global.oe==0 )
			{
				if((lev&1)==0)
					f=1;
				else
					f=0;
				//f=(Global.oe^1)&lev;
				//Global.map[i][7]=null;
			}else
			{
				if((lev&1)==0)
					f=0;
				else
					f=1;
			}
			for(int i=lev;i>0;i--)
			{
				Log.d("map", ">>>>>>>>>>>>>>>>");
				Log.d("map", map());
				
				
				for(int j=0;j<8-f;j++)
				{
					Global.map[i][j]=Global.map[i-1][j];
				
					Ball b=Global.map[i-1][j];
					Global.map[i-1][j]=null;
					if(b!=null)
					{
						//b.setCenterX(Global.columnIndexes[Global.oe&][j]+Global.ballRadius);
						b.setCenterY(Global.layerIndex[i]+Global.ballRadius);
					}
				}
				f^=1;
			}
			Global.oe^=1;
			Global.map[0][7]=null;
			for(int i=0;i<8-Global.oe;i++)
			{
				Ball b=Global.pool.poll();
				b.setStatic(true);
				b.setFalling(false);
				b.setCenterX(Global.columnIndexes[Global.oe][i]+Global.ballRadius);
				b.setCenterY(0+Global.ballRadius);
				Global.map[0][i]=b;
				Global.currentStaticBalls.add(b);
			}
			
			Log.d("map", ">>>>>>>>>>>>>>>>" +Global.maxLayer);
			Log.d("map", map());
			if(check(Global.maxLayer-1))
				Global.maxLayer=Global.maxLayer+1;
			
		}else if(Global.per==700&&!dow)
		{
			Global.per=699;
		}
		
		if((Global.maxLayer-3)>=0&&!check(Global.maxLayer-3))
			Global.maxLayer=Global.maxLayer-1;
		if (Global.layerIndex[Global.maxLayer-1] >= Global.height - 2.0f
				* Global.ballRadius) {
			Activity host = (Activity) con;
			Intent k = new Intent(host, resultActivity.class);
			k.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) ;
			host.finish();
			k.putExtra("status", "lose");
			host.startActivity(k);

		}
	}
	private static int checkCollision(Ball current) {
		for (int i = 0; i < targetBalls.length; i++) {
			Ball temp = targetBalls[i];
			if (temp != null) {
				double distance = Math.sqrt(Math.pow(
						Math.abs(current.getCenterX() - temp.getCenterX()), 2)
						+ Math.pow(
								Math.abs(current.getCenterY()
										- temp.getCenterY()), 2));
				//Global.currentStaticBalls.add(temp);
				if ((distance / 2) < Global.ballRadius)

					return i;
			}
		}
		return -1;
	}

	public static void checkColletion() {

		if(se)
			ballLevel=Global.maxLayer;
		se=false;
		// if(movingBall!=null)
		// Log.d("binary",
		// "isstatic= "+movingBall.isStatic+" cetnery "+movingBall.getCenterY()+" layer "+Global.layerIndex[Global.maxLayer]);
		
		
		Log.d("binary","ball level = " +ballLevel);
		if (movingBall != null
				&& !movingBall.isStatic
				&& movingBall.getCenterY() + Global.ballRadius <= Global.layerIndex[ballLevel]) {
			int index = ((ballLevel - 1) & 1);
			int index2 = (ballLevel) & 1;
			if(Global.oe==1)
			{
				int temp=index2;
				index2=index;
				index=temp;
			}
			int length = Global.columnIndexes[index].length;
			int length2 = Global.columnIndexes[index2].length;
			// int mid=(Global.columnIndexes[index].length+1)/2;
			//
			// if(movingBall.getCenterX()<Global.columnIndexes[index][mid])
			// {
			//
			// }else
			// {
			//
			// }
			boolean found = false;
			int curr = 0, beforeCurr = 0, afterCurr;

			for (int i = 0; i < (Global.MAX_EVEN_LINE_NUMBER_OF_BALLS - index2)
					&& !found; i++) {
				if ((Global.columnIndexes[index2][i] + Global.ballRadius) > movingBall
						.getCenterX()) {
					curr = i;
					found = true;
				}
			}
			if (!found) {
				curr = length - 1;
			}
			afterCurr = (curr + 1) < length ? (curr + 1) : curr;
			beforeCurr = (curr - 1) >= 0 ? (curr - 1) : curr;

			int a[] = new int[3];
			a[0] = beforeCurr;
			a[1] = curr;
			a[2] = afterCurr;
			if ((ballLevel) == 1) {
				System.out.println();
				float dxa = Math.abs(movingBall.getCenterX()
						- Global.columnIndexes[index][afterCurr]
						- Global.ballRadius);
				int nex = afterCurr;
				for (int i = 0; i < 2; i++) {
					float dxb = Math.abs(movingBall.getCenterX()
							- Global.columnIndexes[index][a[i]]
							- Global.ballRadius);
					if (dxa > dxb) {
						dxa = dxb;
						nex = a[i];
					}

				}
				Global.map[0][nex] = movingBall;
				ballOnMove = false;
				Ball[] b = checkScore(0, nex);
				if (b != null) {
					if (Global.soundEnabled)
						hitSound.start();
					if(Global.vibertaeEnabled)
						v.vibrate(300);
					Global.map[0][nex] = null;
					movingBall.setStatic(false);
					movingBall.setFalling(true);
					movingBall.setDy(Global.ballRadius / 8.0f);

					for (int i = 0; b != null && i < b.length; i++) {
						Ball bb = b[i];
						bb.setStatic(false);
						bb.setFalling(true);
						bb.setDy(Global.ballRadius / 8.0f);
						// bb.setDy(bb.getDy()*2);
						movingBalls.add(bb);

					}
					movingBall=null;
					dow=true;
				} else {
					movingBall.setStatic(true);

					movingBall.setCenterX(Global.columnIndexes[index][nex]
							+ Global.ballRadius);
					movingBall.setCenterY(Global.layerIndex[0]
							+ Global.ballRadius);
					Global.currentStaticBalls.add(movingBall);
					Global.maxLayer = Math.max(Global.maxLayer, 2);
					movingBall=null;
					dow=true;
				}

			} else {
				targetBalls[0] = Global.map[ballLevel - 2][beforeCurr];
				targetBalls[1] = Global.map[ballLevel - 2][curr];
				targetBalls[2] = Global.map[ballLevel - 2][afterCurr];
				int next = 0;
				boolean sameRow = false;
				if ((curr = checkCollision(movingBall)) != -1) {
					curr = a[curr];
					Ball temp = Global.map[ballLevel - 2][curr];
					if ((temp.getCenterX() - movingBall.getCenterX()) < 0) {

						if (Math.abs(temp.getCenterX()
								- movingBall.getCenterX()) > (Global.ballRadius / 1.2f)) {
							if (((curr + 1) < length2)
									&& Global.map[ballLevel - 2][curr + 1] == null) {
								sameRow = true;
								next = curr + 1;
							}
						}
						if (!sameRow)

							next = curr + index2;
					} else {
						if (Math.abs(temp.getCenterX()
								- movingBall.getCenterX()) > (Global.ballRadius / 1.2f)) {
							if (((curr - 1) >= 0)
									&& Global.map[ballLevel - 2][curr - 1] == null) {
								next = curr - 1;
								sameRow = true;

							}
						}
						if (!sameRow)
							next = curr - index > 0 ? (curr - index) : 0;
					}
					int nextLayer = 0;
					int targ=0;
					if (sameRow)
					{
						nextLayer = ballLevel - 2;
						targ=index2;
					}
					else{
						nextLayer = ballLevel - 1;
						targ=index;
					}
					Global.map[nextLayer][next] = movingBall;
					ballOnMove = false;

					Ball[] b = checkScore(nextLayer, next);
					if (b != null) {
						
						Log.d("binary", "....."+Global.currentStaticBalls.size());
						if (Global.soundEnabled)
							hitSound.start();
						if(Global.vibertaeEnabled)
							v.vibrate(300);
						Global.map[nextLayer][next] = null;
						movingBall.setStatic(false);
						movingBall.setFalling(true);
						movingBall.setDy(Global.ballRadius / 8.0f);

						for (int i = 0; b != null && i < b.length; i++) {
							Ball bb = b[i];
							bb.setStatic(false);
							bb.setFalling(true);
							bb.setDy(Global.ballRadius / 8.0f);

							// bb.setDy(bb.getDy()*2);
							movingBalls.add(bb);
						}
						for (int i = 0; fallingBallPosition != null
								&& i < fallingBallPosition.length; i++) {
							boolean flag = generator.nextBoolean();
							if (flag)
								fallingBallPosition[i].setDx(3);
							else
								fallingBallPosition[i].setDx(-3);
						}
						fallingBallPosition = null;
						if (Global.currentStaticBalls.size() == 0) {
							Activity host = (Activity) con;
							Intent k = new Intent(host, resultActivity.class);
							
							host.finish();
							k.putExtra("status", "win");
							host.startActivity(k);

						}
						movingBall=null;
						dow=true;
					} else {
						movingBall.setStatic(true);
						movingBall
								.setCenterX(Global.columnIndexes[targ][next]
										+ Global.ballRadius);
						movingBall.setCenterY(Global.layerIndex[nextLayer]
								+ Global.ballRadius);
						
						if (movingBall.getCenterY() >= Global.height - 3
								* Global.ballRadius) {
							Activity host = (Activity) con;
							Intent k = new Intent(host, resultActivity.class);
							k.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) ;
							host.finish();
							k.putExtra("status", "lose");
							host.startActivity(k);

						} else {

							Global.currentStaticBalls.add(movingBall);
							Global.maxLayer = Math.max(Global.maxLayer,
									nextLayer + 2);
							movingBall=null;
							dow=true;
						}
					}

				}

				// Log.d("binary", "start= "+start+" end= "+end+" "+ballLevel);
				if (movingBall!=null&&(Global.layerIndex[ballLevel - 2] + Global.ballRadius) >= movingBall
						.getCenterY())
				{
					System.out.println();
					ballLevel = ballLevel - 1;
				}
			}
		}
		if (Global.currentStaticBalls.size() == 0) {
			Activity host = (Activity) con;
			Intent k = new Intent(host, resultActivity.class);
			//k.setClass(packageContext, cls)
			k.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) ;
			host.finish();
			k.putExtra("status", "win");
			host.startActivity(k);

		}
	}

	private static Ball[] checkScore(int x, int y) {
		Queue<Integer> queue = new LinkedList<Integer>();
		Queue<Integer> fallingBalls = new LinkedList<Integer>();
	
		int count = 1;
		int num = x * Global.map[0].length + y;
		boolean[][] marked = new boolean[Global.map.length][Global.map[0].length];
		marked[x][y] = true;
		// fallingBalls.add(num);
		count = checkNeighbours(num, queue, fallingBalls, marked);
		if (count > 1) {
			fallingBallPosition = new Ball[queue.size()];
			for (int i = 0; i < queue.size(); i++) {
				int temp = queue.poll();
				fallingBallPosition[i] = Global.map[temp / Global.map[0].length][temp
						% Global.map[0].length];
				queue.add(temp);
			}
			while (!queue.isEmpty()) {
				int topOfQueue = queue.poll();
				checkNeighbours(topOfQueue, queue, fallingBalls, marked);
			}
		}
		if (fallingBalls.size() >= 2) {
			// WE HAVE TO DETERMINE WHAT ARE THE BALLS THAT
			// ARE GOING TO FALL WITH THE ONES IN THIS QUEUE!
			ArrayList<Ball> list = new ArrayList<Ball>();
			while (!fallingBalls.isEmpty()) {
				int top = fallingBalls.poll();
				x = top / Global.map[0].length;
				y = top % Global.map[0].length;
					list.add(Global.map[x][y]);
				Global.map[x][y] = null;
				if (x % 2 != 0) {
					if (x < Global.map.length - 1
							&& Global.map[x + 1][y] != null
							&& !marked[x + 1][y]) {
						fallingBalls.add((x + 1) * Global.map[0].length + (y));
		//				list.add(Global.map[x + 1][y]);
						marked[x + 1][y] = true;

					}
					// CHECK RIGHT
					if (x < Global.map.length - 1&&(y+1)<8
							&& Global.map[x + 1][y + 1] != null
							&& !marked[x + 1][y + 1]) {
						fallingBalls.add((x + 1) * Global.map[0].length
								+ (y + 1));
			//			list.add(Global.map[x + 1][y + 1]);
						marked[x + 1][y + 1] = true;

					}

				} else {
					// CHECK LEFT
					if (x < Global.map[0].length - 1 && y > 0
							&& Global.map[x + 1][y - 1] != null
							&& !marked[x + 1][y - 1]) {
						fallingBalls.add((x + 1) * Global.map[0].length
								+ (y - 1));
				//		list.add(Global.map[x + 1][y - 1]);
						marked[x + 1][y - 1] = true;

					}
					// CHECK RIGTH
					if (x < Global.map[0].length - 1
							&& Global.map[x + 1][y] != null
							&& !marked[x + 1][y]) {
						fallingBalls.add((x + 1) * Global.map[0].length + (y));
					//	list.add(Global.map[x + 1][y]);
						marked[x + 1][y] = true;

					}

				}
				/*
				 * // check lower row if (x < Global.map.length - 1) { // CHECK
				 * LEFT: if (y > 0 && Global.map[x + 1][y - 1] != null &&
				 * !marked[x + 1][y - 1]) { fallingBalls.add((x + 1) *
				 * Global.map[0].length + (y - 1)); list.add(Global.map[x + 1][y
				 * - 1]); // Global.map[x + 1][y - 1] = null; marked[x + 1][y -
				 * 1] = true; } // CHECK RIGHT if (Global.map[x + 1][y] != null
				 * && !marked[x + 1][y]) { list.add(Global.map[x + 1][y]);
				 * fallingBalls.add((x + 1) * Global.map[0].length + (y)); //
				 * Global.map[x + 1][y] = null; marked[x + 1][y] = true; } }
				 */

			}
			// String[] arr = list.toArray(new String[list.size()]);

			Ball[] array = list.toArray(new Ball[list.size()]);
			Global.score += (array.length)*5;
			return array;
		}
		return null;
	}

	private static int checkNeighbours(int num, Queue<Integer> queue,
			Queue<Integer> falling, boolean marked[][]) {
		int x = num / Global.map[0].length;
		int y = num % Global.map[0].length;
		int ballColor = Global.map[x][y].getColor();
		int count = 1;
		// CASE ODD ROW ! NO PROBLEM:
		// LEFT IS THE SAME INDEX
		// RIGHT IS INDEX + 1 NO FURTHER CHECK ARE NEEDED
		if ((((x % 2) != 0)&& Global.oe==0) || (((x % 2) == 0)&& Global.oe==1)) {
			// CHECK UPPER ROW
			// CHECK LEFT
			if (x > 0 && Global.map[x - 1][y] != null && !marked[x - 1][y]
					&& Global.map[x - 1][y].getColor() == ballColor) {
				queue.add((x - 1) * Global.map[0].length + (y));
				falling.add((x - 1) * Global.map[0].length + (y));
				count++;
				marked[x - 1][y] = true;

			}
			// CHECK RIGHT
			if (x > 0&&(y+1)<8 && Global.map[x - 1][y + 1] != null
					&& !marked[x - 1][y + 1]
					&& Global.map[x - 1][y + 1].getColor() == ballColor) {
				queue.add((x - 1) * Global.map[0].length + (y + 1));
				falling.add((x - 1) * Global.map[0].length + (y + 1));
				count++;
				marked[x - 1][y + 1] = true;

			}

			// CHECK LOWER ROW
			if (x < Global.map.length - 1 && Global.map[x + 1][y] != null
					&& !marked[x + 1][y]
					&& Global.map[x + 1][y].getColor() == ballColor) {
				queue.add((x + 1) * Global.map[0].length + (y));
				falling.add((x + 1) * Global.map[0].length + (y));
				count++;
				marked[x + 1][y] = true;

			}
			// CHECK RIGHT
			if (x < Global.map.length - 1 &&(y+1)<8&& Global.map[x + 1][y + 1] != null
					&& !marked[x + 1][y + 1]
					&& Global.map[x + 1][y + 1].getColor() == ballColor) {
				queue.add((x + 1) * Global.map[0].length + (y + 1));
				falling.add((x + 1) * Global.map[0].length + (y + 1));
				count++;
				marked[x + 1][y + 1] = true;

			}

		}
		// CASE EVEN
		else {
			// CASE UPPER

			// CHECK LEFT
			if (x > 0 && y > 0 && Global.map[x - 1][y - 1] != null
					&& !marked[x - 1][y - 1]
					&& Global.map[x - 1][y - 1].getColor() == ballColor) {
				queue.add((x - 1) * Global.map[0].length + (y - 1));
				falling.add((x - 1) * Global.map[0].length + (y - 1));
				count++;
				marked[x - 1][y - 1] = true;

			}
			// CHECK RIGTH
			if (x > 0 && Global.map[x - 1][y] != null && !marked[x - 1][y]
					&& Global.map[x - 1][y].getColor() == ballColor) {
				queue.add((x - 1) * Global.map[0].length + (y));
				falling.add((x - 1) * Global.map[0].length + (y));
				count++;
				marked[x - 1][y] = true;

			}
			// CASE LOWER

			// CHECK LEFT
			if (x < Global.map[0].length - 1 && y > 0
					&& Global.map[x + 1][y - 1] != null
					&& !marked[x + 1][y - 1]
					&& Global.map[x + 1][y - 1].getColor() == ballColor) {
				queue.add((x + 1) * Global.map[0].length + (y - 1));
				falling.add((x + 1) * Global.map[0].length + (y - 1));
				count++;
				marked[x + 1][y - 1] = true;

			}
			// CHECK RIGTH
			if (x < Global.map[0].length - 1 && Global.map[x + 1][y] != null
					&& !marked[x + 1][y]
					&& Global.map[x + 1][y].getColor() == ballColor) {
				queue.add((x + 1) * Global.map[0].length + (y));
				falling.add((x + 1) * Global.map[0].length + (y));
				count++;
				marked[x + 1][y] = true;

			}
		}

		// CHECK LEFT
		if (y > 0 && Global.map[x][y - 1] != null && !marked[x][y - 1]
				&& Global.map[x][y - 1].getColor() == ballColor) {
			queue.add((x) * Global.map[0].length + (y - 1));
			falling.add((x) * Global.map[0].length + (y - 1));
			count++;
			marked[x][y - 1] = true;

		}
		// CHECK RIGHT
		if (y < Global.map[0].length - 1 && Global.map[x][y + 1] != null
				&& !marked[x][y + 1]
				&& Global.map[x][y + 1].getColor() == ballColor) {
			queue.add((x) * Global.map[0].length + (y + 1));
			falling.add((x) * Global.map[0].length + (y + 1));
			count++;
			marked[x][y + 1] = true;

		}

		/*
		 * 
		 * // check upper row if (x > 0) { // CHECK LEFT if (y > 0 &&
		 * Global.map[x - 1][y - 1] != null && Global.map[x - 1][y -
		 * 1].getColor() == ballColor && !marked[x - 1][y - 1]) { queue.add((x -
		 * 1) * Global.map[0].length + (y - 1)); falling.add((x - 1) *
		 * Global.map[0].length + (y - 1)); count++; marked[x - 1][y - 1] =
		 * true; } // CHECK RIGHT if (Global.map[x - 1][y] != null &&
		 * Global.map[x - 1][y].getColor() == ballColor && !marked[x - 1][y]) {
		 * queue.add((x - 1) * Global.map[0].length + (y)); falling.add((x - 1)
		 * * Global.map[0].length + (y)); count++; marked[x - 1][y] = true; } }
		 * // check lower row if (x < Global.map.length - 1) { // CHECK LEFT: if
		 * (y > 0 && Global.map[x + 1][y - 1] != null && Global.map[x + 1][y -
		 * 1].getColor() == ballColor && !marked[x + 1][y - 1]) { queue.add((x +
		 * 1) * Global.map[0].length + (y - 1)); falling.add((x + 1) *
		 * Global.map[0].length + (y - 1)); count++; marked[x + 1][y - 1] =
		 * true; } // CHECK RIGHT if (Global.map[x + 1][y] != null &&
		 * Global.map[x + 1][y].getColor() == ballColor && !marked[x + 1][y]) {
		 * queue.add((x + 1) * Global.map[0].length + (y)); falling.add((x + 1)
		 * * Global.map[0].length + (y)); count++; marked[x + 1][y] = true; } }
		 * // CHECK LEFT if (y > 0 && Global.map[x][y - 1] != null &&
		 * Global.map[x][y - 1].getColor() == ballColor && !marked[x][y - 1]) {
		 * queue.add((x) * Global.map[0].length + (y - 1)); falling.add((x) *
		 * Global.map[0].length + (y - 1)); count++; marked[x][y - 1] = true; }
		 * // CHECK RIGHT if (y < Global.map[0].length - 1 && Global.map[x][y +
		 * 1] != null && Global.map[x][y + 1].getColor() == ballColor &&
		 * !marked[x][y + 1]) { queue.add((x) * Global.map[0].length + (y + 1));
		 * falling.add((x) * Global.map[0].length + (y + 1)); count++;
		 * marked[x][y + 1] = true; }
		 */
		return count;
	}

	public static void updateBallMove() {
		// if(movingBall!=null)
		// movingBall.move();
		//synchronized (getHolder()) {
		
			int siz = movingBalls.size();
			Log.d("binary","moving ball size = "+siz+" current static size = "+Global.currentStaticBalls.size());
			for (int j = 0; j < siz; j++) {
				Ball i = movingBalls.poll();
				i.move();
				boolean flag = true;
				if (i.getCenterX() < Global.ballRadius
						|| i.getCenterX() > (Global.width - Global.ballRadius)) {
					if (!i.isFalling)
						i.setDx(-i.getDx());
					else
					{
						flag = true;
					}
				}
				// else
				if (i.getCenterY() > (Global.height + 2.0f*Global.ballRadius)) {
					i.setStatic(true);
					i.setFalling(false);
					Global.addToPool(i);

				} else if (flag) {
					movingBalls.add(i);
				}
			}

		}
	//}

	@Override
	protected void onDraw(Canvas canvas) {

		int height = Global.height;
		int width = getWidth();
		
		if (canvas != null) {
			paint.setColor(Color.WHITE);
			canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
			// canvas.drawBitmap(scaled, 0, 0, null);
			paint.setColor(Color.BLACK);
			System.out.println();
			 paint.setTextSize((getWidth()*getHeight())/3000);
			   canvas.drawText("Score: "+Global.score, 0, getHeight()-10, paint);
		
			
			// for (Ball sb : Global.currentStaticBalls) {
			// paint.setColor(sb.getColor());
			// canvas.drawCircle(sb.getCenterX(), sb.getCenterY(),
			// Global.ballRadius, paint);
			// }
			int siz = Global.currentStaticBalls.size();
			for (int i = 0; i < siz; i++) {
				Ball sb = Global.currentStaticBalls.poll();

				paint.setColor(sb.getColor());
				canvas.drawCircle(sb.getCenterX(), sb.getCenterY(),
						Global.ballRadius, paint);
				if (sb.isStatic && !sb.isFalling)
					Global.currentStaticBalls.add(sb);
				else {
					Log.d("binary", " x = "+sb.getCenterX()+" y= "+sb.getCenterY());
					System.out.println();
				}
			}

			paint.setColor(misselBall.getColor());

			canvas.drawCircle(misselBall.getCenterX(), misselBall.getCenterY(),
					Global.ballRadius, paint);

			for (int i = 0; i < 2; i++) {
				paint.setColor(nextBalls[i].getColor());

				canvas.drawCircle(nextBalls[i].getCenterX(),
						nextBalls[i].getCenterY(), Global.ballRadius, paint);
			}
			int i = 0;
int size=movingBalls.size();
			for (int j = 0; j < size; j++) {
				Ball sb = movingBalls.poll();
				paint.setColor(sb.getColor());
				if (sb.getCenterX() == 0 && sb.getCenterY() == 0)
					System.out.println();

				// Log.d("index", "i= " + (i++) + " x= " + sb.getCenterX() +
				// " y= "
				// + sb.getCenterY());
				canvas.drawCircle(sb.getCenterX(), sb.getCenterY(),
						Global.ballRadius, paint);
				if (!sb.isStatic)
					movingBalls.add(sb);
			}
		}

		// float radius=30;

		// float cx = radius + margin;

	}

	float getDistance(float x1, float x2, float y1, float y2) {
		return (float) Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
	}

	public void moveIndex(Ball b1, Ball b2) {
		b2.setCenterX(b1.getCenterX());
		b2.setCenterY(b1.getCenterY());
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// if (event.getAction() == event.ACTION_OUTSIDE) {

		if (!ballOnMove) {
			ballOnMove = true;
			float x1 = misselBall.getCenterX();
			float y1 = misselBall.getCenterY();
			float x2 = event.getX();
			float y2 = event.getY();
			float d = getDistance(x1, x2, y1, y2);
			float dx = x2 - x1;
			float dy = Math.abs(y1 - y2);
			float ndx = dx / d;
			float ndy = dy / d;
			misselBall.setStatic(false);
			misselBall.setFalling(false);
			misselBall.setDx(3.0f * ndx);
			misselBall.setDy(3.0f * ndy);
			Ball bb = misselBall;
			bb.setFalling(false);
			movingBalls.add(bb);
			movingBall = bb;
			ballLevel = Global.maxLayer;
			Log.d("pool",">> poolsize = "+Global.pool.size()+" ");
			Ball b = Global.pool.poll();
			if (Global.currentStaticBalls.size() <= 5
					&& Global.currentStaticBalls.size() > 0) {
				Ball temp = Global.currentStaticBalls.poll();
				int color = temp.getColor();
				int count=0;
				while (b.getColor() != color && count<30) {
					count++;
					Global.addToPool(b);
					b = Global.pool.poll();
				}
				Global.currentStaticBalls.add(temp);
			}
			b.setStatic(true);
			b.setFalling(false);

			moveIndex(nextBalls[1], b);
			moveIndex(nextBalls[0], nextBalls[1]);
			moveIndex(misselBall, nextBalls[0]);
			misselBall = nextBalls[0];
			nextBalls[0] = nextBalls[1];
			nextBalls[1] = b;
se=true;
dow=false;
			// invalidate();
			// updateBallMove();
		}

		return super.onTouchEvent(event);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// seting the scale of back ground image
		/*
		 * Bitmap background = BitmapFactory.decodeResource(getResources(),
		 * R.drawable.ic_launcher); float scale = (float) background.getHeight()
		 * / (float) getHeight(); int newWidth =
		 * Math.round(background.getWidth() / scale); int newHeight =
		 * Math.round(background.getHeight() / scale); scaled =
		 * Bitmap.createScaledBitmap(background, newWidth, newHeight, true);
		 */

		try {
			if (Global.soundEnabled) {
				sound = MediaPlayer.create(this.getContext(), R.raw.soun);
				hitSound = MediaPlayer.create(this.getContext(), R.raw.collect);
				scoreSound = MediaPlayer.create(this.getContext(),
						R.raw.collision);
				sound.start();
				sound.setLooping(true);
				
			}
			if(Global.vibertaeEnabled)
				v= (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
		} catch (Exception e) {
		}

		thread.setRunning(true);
		thread.start();

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		boolean retry = true;
		while (retry) {
			try {
				if (Global.soundEnabled) {
					sound.setLooping(false);
					sound.stop();
				}
				thread.setRunning(false);
				thread.join();

				retry = false;
			} catch (InterruptedException e) {
				// try again shutting down the thread
			}
		}

	}
}
